package geo

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"sweetsunnyflower/pkg/config"
	"sweetsunnyflower/pkg/logger"
	"sync"
)

type Geo struct {
	http.Client
}

var once sync.Once
var geo *Geo

func UnmarshalSearch(data []byte) (*Search, error) {
	r := &Search{}
	err := json.Unmarshal(data, &r)
	return r, err
}

func (r *Search) Marshal() ([]byte, error) {
	return json.Marshal(r)
}

type Search struct {
	Status    int64   `json:"status"`
	Message   string  `json:"message"`
	Count     int64   `json:"count"`
	RequestID string  `json:"request_id"`
	Data      []Datum `json:"data"`
	Region    Region  `json:"region"`
}

type Datum struct {
	ID       string   `json:"id"`
	Title    string   `json:"title"`
	Address  string   `json:"address"`
	Tel      string   `json:"tel"`
	Category string   `json:"category"`
	Type     int64    `json:"type"`
	Location Location `json:"location"`
	AdInfo   AdInfo   `json:"ad_info"`
}

type AdInfo struct {
	Adcode   int64  `json:"adcode"`
	Province string `json:"province"`
	City     string `json:"city"`
	District string `json:"district"`
}

type Location struct {
	Lat float64 `json:"lat"`
	Lng float64 `json:"lng"`
}

type Region struct {
	Title string `json:"title"`
}

func NewGeo() *Geo {
	once.Do(func() {
		geo = &Geo{}
	})
	return geo
}

func (g *Geo) Search(keyword string) (*Search, error) {

	APIURL := config.GetString("geo.api_url")

	if APIURL == "" {
		panic("api_url is empty")
	}

	APIKEY := config.GetString("geo.api_key")

	if APIKEY == "" {
		panic("api_key is empty")
	}

	queryUrl := fmt.Sprintf("%s?key=%s&keyword=%s&boundary=region(大同,1)", APIURL, APIKEY, keyword)

	resp, err := g.Get(queryUrl)

	if err != nil {
		logger.ErrorString("geo", "search get", err.Error())
		return nil, err
	}

	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)

	if err != nil {
		logger.ErrorString("geo", "search read", err.Error())
		return nil, err
	}

	return UnmarshalSearch(body)
}
